package com.springcloud.gateway.filter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.springcloud.gateway.service.FeignService;


@Service
public class AccessFilter extends ZuulFilter  {

	private static Logger log = LoggerFactory.getLogger(AccessFilter.class);


	@Autowired
	private  FilterConfig filterConfig;
	
	@Autowired
	FeignService feignService;

	@Override
	public String filterType() {
		return "pre";
	}

	@Override
	public int filterOrder() {
		return 0;
	}

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public Object run() {
		
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		HttpServletResponse response = ctx.getResponse();
		ctx.getResponse().setContentType("application/json;charset=UTF-8");
		//ctx.setSendZuulResponse(true);
		
		String ignoresParam = filterConfig.getIgnores();
		String[] ignoreArray = ignoresParam.split(",");  
		log.info("=========="+String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
		
		Object accessToken = request.getHeader("accessToken");
		Object refreshToken = request.getHeader("refreshToken");
		/**
		 * 只判断accessToken存在即可
		 */
		if(accessToken==null || accessToken.equals("null")){
			accessToken = null;
		}
		boolean flag = false;
		for(int i=0;i<ignoreArray.length;i++){
			if(request.getRequestURL().toString().contains(ignoreArray[i])){
				flag = true;
			}
		}

		if(!flag&&accessToken == null){ //token 不存在
			log.info("token is empty");
			Map<String,Object> map = Collections.synchronizedMap(new HashMap<>());
			map.put("code", "401");
			map.put("massage", "请登录");
			map.put("result", false);
			ctx.setSendZuulResponse(false);
			ctx.setResponseStatusCode(401);
			ctx.setResponseBody(JSON.toJSONString(map));
		}else if(!flag&&accessToken != null){  //校验token 存在
			try {
				JSONObject accessJSON = feignService.verification(accessToken.toString(), "0");
				if(!"200".equals(accessJSON.get("code"))) {//先校验accessToken 是否失效 
					ctx.setSendZuulResponse(false);
					ctx.setResponseStatusCode(401);
					ctx.setResponseBody(accessJSON.toJSONString());
				}else 
					return null;
				
				if(refreshToken != null) { //refreshToken存在
					ctx.setSendZuulResponse(true);
					ctx.setResponseStatusCode(200);
					ctx.setResponseBody(null);
					JSONObject refreshJSON = feignService.verification(refreshToken.toString(), "1");
					if(!"200".equals(refreshJSON.get("code"))) { // 再校验refreshToken是否失效
						ctx.setSendZuulResponse(false);
						ctx.setResponseStatusCode(401);
						ctx.setResponseBody(refreshJSON.toJSONString());
					}
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		log.info("access token ok");
		return null;
	}

}
